package com.binance.gateway.app.base.helper;

import com.alibaba.fastjson.JSONObject;
import com.binance.gateway.app.base.dto.SessionDto;
import com.binance.gateway.app.constant.CacheKey;
import com.binance.gateway.app.constant.Constant;
import com.binance.gateway.app.constant.TokenType;
import com.binance.master.utils.RedisCacheUtils;
import com.ctrip.framework.apollo.ConfigService;
import com.wenfex.common.security.KeyFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Component
@Slf4j
public class SessionHelper {
    private static final long TOKEN_TIMEOUT = 24 * 60 * 60L;
    private static final long WEB_TOKEN_TIMEOUT = 10 * 60 * 60L;
    @Resource
    private BaseHelper baseHelper;

    public SessionDto getSession(String token) {
        // 前端会传空及undefined 过来，提前判定为未登录
        if (StringUtils.isBlank(token) || StringUtils.equals(token, "undefined ")) {
            return null;
        }
        // 检查token跟clientType是否匹配，目前仅打印log
        if (!baseHelper.checkTokenType(token)) {
            return null;
        }
        // token不为空，查找token对应的内容
        JSONObject attr = getAndRenewToken(token);
        if (attr != null) {
            SessionDto sessionVo = new SessionDto();
            sessionVo.setUserId(attr.getString(Constant.SESSION_USERID));
            sessionVo.setEmail(attr.getString(Constant.SESSION_USER_EMAIL));
            sessionVo.setLoginTime(attr.getString(Constant.LAST_LOGIN_TIME));
            sessionVo.setCsrfToken(attr.getString(Constant.COOKIE_CSRFTOKEN));
            sessionVo.setToken(token);
            return sessionVo;
        }
        return null;
    }


    /**
     * 获取并延长token有效期
     * 
     * @param token
     * @return
     */
    public JSONObject getAndRenewToken(String token) {
        final String key = CacheKey.getToken(token);
        JSONObject sessionAttr = RedisCacheUtils.get(key, JSONObject.class);
        if (sessionAttr == null) {
            return null;
        }
        if (StringUtils.equals(ConfigService.getAppConfig().getProperty("token.del.switch", "Y"), "Y") && StringUtils.isNotBlank(sessionAttr.getString(Constant.LAST_LOGIN_TIME))) {
            try {
                LocalDateTime localDate = LocalDateTime.parse(sessionAttr.getString(Constant.LAST_LOGIN_TIME), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
                if (localDate.isBefore(LocalDateTime.parse("2019-01-01T00:00:00"))) {
                    log.info("delete old token before 2019-01-01,time is:{},token is:{}", sessionAttr.getString(Constant.LAST_LOGIN_TIME), StringUtils.left(token, Constant.TOKEN_SHOW_LEN));
                    RedisCacheUtils.del(key);
                }
            } catch (Exception e) {
                log.error("delete old token fail", e);
            }
        }
        RedisCacheUtils.expire(key, getTimeout(token));
        return sessionAttr;
    }

    private long getTimeout(String token) {
        long timeout = WEB_TOKEN_TIMEOUT;
        if (StringUtils.startsWith(token, TokenType.app.name())) {
            timeout = TOKEN_TIMEOUT;
        }
        return timeout;
    }

    private String createKey(String clientType, String userId) {
        return KeyFactory.createTokenKey(clientType, userId);
    }

    public String getAppToken(String clientType, String userId) {
        if (StringUtils.isEmpty(clientType) || StringUtils.isEmpty(userId)) {
            return null;
        }
        String key = createKey(clientType, userId);
        String token = RedisCacheUtils.get(key);
        return token;
    }
}
